15

I'm trying to limit the entries to a specific format.

If the entry has 5500 or 5100 such as 01\01-5500-000-00 then I want to have this:

^[0-9]{2,}\\[0-9]{2}\-[0-9]{4}\-[0-9]{3}\-$

But if the entry has anything other than 5500 or 5100 I want to have this:

^[0-9]{2,}\\[0-9]{2}\-[0-9]{4}\-[0-9]{3}\-[0-9]{2}$

How can this be accomplished with the if then else idea?

5
  • 4
    What language are you using? What have you tried? Commented Sep 29, 2015 at 20:09
  • ^[0-9]{2,}\\[0-9]{2}-5[15]00-[0-9]{3}-$|^[0-9]{2,}\\[0-9]{2}-(?!5[15]00)[0-9]{4}-[0-9]{3}-[0-9]{2}$ Commented Sep 29, 2015 at 20:13
  • I've used webtoolkitonline.com/regular-expression-tester.html to help me correctly create the expression. And I've tried using the pipe with 5500 in parenthesis like this: (?=.*5500)|^[0-9]{2,}\[0-9]{2}\-[0-9]{4}\-[0-9]{3}\-[0-9]{2}$ - not correct Commented Sep 29, 2015 at 20:15
  • That tool only supports JS as I can see. But it is still possible. Commented Sep 29, 2015 at 20:18
  • By the way, 01\01-5500-000-00 does not match your first pattern. is it supposed to fail? Also, is the trailing "-" in the first pattern intentional? Commented Sep 29, 2015 at 20:43

3 Answers 3

20

Conditional regex syntax is not supported by JavaScript regex engine, but it can be worked around with a non-capturing group containing 2 alternatives:

  1. One with the positive look-ahead and

  2. The second with the reversed, negative look-ahead.

This regex meets your criteria and is JavaScript compatible:

^(?:(?=.*\b5[15]00\b)[0-9]{2,}\\[0-9]{2}-[0-9]{4}-[0-9]{3}-|(?!.*\b5[15]00\b)[0-9]{2,}\\[0-9]{2}-[0-9]{4}-[0-9]{3}-[0-9]{2})$

See regex demo

Let me break it down:

  • ^ - Start of string
  • (?:
    • (?=.*\b5[15]00\b)[0-9]{2,}\\[0-9]{2}-[0-9]{4}-[0-9]{3}- - First alternative with the (?=.*\b5[15]00\b) look-ahead that requires a whole word 5500 or 5100 inside the string, and the first pattern you have
    • | - alternation operator
    • (?!.*\b5[15]00\b)[0-9]{2,}\\[0-9]{2}-[0-9]{4}-[0-9]{3}-[0-9]{2}) - Second alternative that is prepended with the (?!.*\b5[15]00\b) negative look-ahead that makes sure there is no 5100 or 5500 inside the string, and only then matches your second pattern.
  • $ - end of string.
Sign up to request clarification or add additional context in comments.

Comments

3

Use conditionals, Eg:

(?(?=regex)then|else): [0-9]{2,}\\[0-9]{2}\-(?(?=5[15]00)[0-9]{4}\-[0-9]{3}\-|[0-9]{4}\-[0-9]{3}\-[0-9]{2})

Regex conditionals example: [email protected]

In case that you're using a regex engine that is not PCRE based, you can be able to mimic the functionality by doing the following:

((?=positive-regex-statement)then|(?!negavite-regex-statement)then)

Eg.

^[0-9]{2,}\\[0-9]{2}\-((?=5[15]00)[0-9]{4}\-[0-9]{3}\-|[0-9]{4}\-|(?!5[15]00)[0-9]{4}\-[0-9]{3}\-[0-9]{2})$

Mimic regex conditionals example: [email protected]

3 Comments

@user974061: Could you please advise what is the programming language that you are using with this regular expressions? (The conditionals are supported only by PCRE like engines).
@Houseman: Did you actually read the whole post, or just down-voted for no reason? I provided an answer for non PCRE based engines (which also includes Javascript).
Thanks for fixing that, @Revo, I was a little confused.
2

Replace this part of the pattern [0-9]{4} with the literal values for 5100/5500:

/^\d{2,}\\\d{2}-(?:5[15]00-\d{3}-|(?!5[15]00)\d{4}-\d{3}-\d{2})$/
  • [0-9] is the same thing as \d in JavaScript
  • For the else part, use the negative lookahead (?!5[15]00)\d{4} to guarantee it's not 5100/5500.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.